import {
  CanActivate,
  ExecutionContext,
  Injectable,
  Inject,
  UnauthorizedException,
} from '@nestjs/common'
// import { Observable } from 'rxjs';
import { Reflector } from '@nestjs/core'
import { Model } from 'mongoose'
import { InjectModel } from '@nestjs/mongoose'
import { WxUser, UserDocument } from '@libs/db/schemas/user.schema'
import { Enforcer } from 'casbin'
import CONSTANTS from './constants'

// type CtxType = boolean | Promise<boolean> | Observable<boolean>;

@Injectable()
export class RolesGuard implements CanActivate {
  constructor(
    private reflector: Reflector,
    @InjectModel(WxUser.name) private WxUserModel: Model<UserDocument>,
    @Inject(CONSTANTS.CASBIN.ENFORCER_PROVIDER_NAME) private e: Enforcer
  ) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    // 取得SetMetadata
    const roles = this.reflector.get<any>('roles', context.getHandler())
    // 取得Controller
    const controllerName = this.reflector.get<string[]>('path', context.getClass())
    // 取得user
    const req = context.switchToHttp().getRequest()
    const user = req.user
    console.log(user, roles, controllerName)
    if (user) {
      const { id } = user
      const res = await this.WxUserModel.findById(id).exec()
      const { role } = res
      const bool = (await this.e.enforce(role, roles.obj, roles.act)) === true
      return bool
    } else {
      // 讲道理不会到这里，重新登录
      throw new UnauthorizedException('未找到用户登录信息')
    }
  }
}
